package com.dctp.common.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.dctp.common.cache.RoleCache;
import com.dctp.common.vo.TipCode;
import com.jfinal.core.Controller;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Record;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class BaseController extends Controller {

    public Record getRequestUser() {
        return (Record) getRequest().getAttribute("reqUser");
    }

    private static final Map<Integer, String> LEVEL_FIELD_MAP = Map.of(
            2, "bottom_role_user_id",
            3, "middle_role_user_id",
            4, "top_role_user_id"
    );


    public String getGroupByIdKey() {

        Record user = getRequestUser();
        Integer superAdmin = user.getInt("super_admin");
        if (superAdmin != null && superAdmin == 1) {
            return LEVEL_FIELD_MAP.get(4);
        }

        //内部管理人员
        if (user.getInt("type") == 0) {
            return LEVEL_FIELD_MAP.get(4);
        }

        Long userRoleId = user.getLong("user_role_id");
        Record role = RoleCache.getById(userRoleId);
        if (role == null) {
            throw new RuntimeException("角色状态异常，请联系管理员");
        }
        Integer level = role.getInt("level");
        if (level == 1) {
            throw new RuntimeException("普通用户不能登录后台");
        }
        return LEVEL_FIELD_MAP.get(level - 1);
    }
    public String getRoleField(Long roleId) {
        return LEVEL_FIELD_MAP.get(roleId.intValue());
    }

    public String getFilterField(Record ... records) {

        Record user = getRequestUser();
        if (records != null && records.length > 0) {
            user = records[0];
        }
        Integer superAdmin = user.getInt("super_admin");
        if (superAdmin != null && superAdmin == 1) {
            return null; // 超级管理员不需要过滤
        }

        if (user.getInt("type") == 0) {
            return null;
        }

        Long userRoleId = user.getLong("user_role_id");
        Record role = RoleCache.getById(userRoleId);
        if (role == null) {
            throw new RuntimeException("角色状态异常，请联系管理员");
        }
        Integer level = role.getInt("level");
        String field = LEVEL_FIELD_MAP.get(level);
        if (field == null) {
            throw new RuntimeException("角色层级未配置过滤字段，请联系管理员");
        }
        return field;
    }


    public Long getUserId() {
        Record user = getRequestUser();
        if (null == user)
            return null;
        return user.getLong("id");
    }

    protected <T> T getRequired(String name, Class<T> clazz) {
        return getRequired(name, clazz, null, null);
    }

    protected <T> T getRequired(String name, Class<T> clazz, Class<?> validatorClass, String methodName) {
        String rawValue = getPara(name);
        if (StrKit.isBlank(rawValue)) {
            throw new RuntimeException(TipCode.PARAM_EMPTY);
        }

        // 自定义验证器处理
        if (validatorClass != null) {
            try {
                Method method = validatorClass.getMethod(methodName, String.class);
                Object result = method.invoke(null, rawValue);
                if (result instanceof Boolean && !(Boolean) result) {
                    throw new RuntimeException(TipCode.PARAM_ERROR);
                }
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(TipCode.PARAM_ERROR);
            } catch (Exception e) {
                throw new RuntimeException(TipCode.PARAM_ERROR);
            }
        }

        try {
            if (clazz == String.class)
                return clazz.cast(rawValue);
            if (clazz == Integer.class)
                return clazz.cast(Integer.valueOf(rawValue));
            if (clazz == Long.class)
                return clazz.cast(Long.valueOf(rawValue));
            if (clazz == Boolean.class)
                return clazz.cast(Boolean.valueOf(rawValue));
            if (clazz == Double.class)
                return clazz.cast(Double.valueOf(rawValue));
            if (clazz == BigDecimal.class)
                return clazz.cast(new BigDecimal(rawValue));
            if (clazz == Date.class)
                return clazz.cast(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(rawValue));
        } catch (Exception e) {
            throw new RuntimeException(TipCode.PARAM_ERROR);
        }
        throw new RuntimeException(TipCode.PARAM_ERROR);
    }

    /**
     * 支持默认值的版本
     */
    @SuppressWarnings("unchecked")
    protected <T> T getRequired(String name, Class<T> clazz, T defaultValue) {
        String rawValue = getPara(name);
        if (StrKit.isBlank(rawValue)) {
            return defaultValue;
        }
        try {
            if (clazz == String.class) {
                return (T) rawValue;
            } else if (clazz == Integer.class) {
                return (T) Integer.valueOf(rawValue);
            } else if (clazz == Long.class) {
                return (T) Long.valueOf(rawValue);
            } else if (clazz == Boolean.class) {
                return (T) Boolean.valueOf(rawValue);
            } else if (clazz == Double.class) {
                return (T) Double.valueOf(rawValue);
            } else if (clazz == BigDecimal.class) {
                return (T) new BigDecimal(rawValue);
            } else if (clazz == Date.class) {
                return (T) new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(rawValue);
            } else {
                return defaultValue;
            }
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /** 把请求体 JSON → Record （兼容 JFinal 5.2） */
    protected Record jsonBody() {
        String raw = getRawData();
        if (StrKit.isBlank(raw)) {
            return new Record();
        }
        try {
            // 解析成 Map<String,Object>
            Map<String, Object> map = JSON.parseObject(raw,
                    new TypeReference<>() {
                    });
            Record record = new Record();
            record.setColumns(map);
            setAttr("jsonBody",record);
            return record;
        } catch (Exception e) {
            throw new RuntimeException(TipCode.PARAM_ERROR + ": JSON 解析失败", e);
        }
    }


    protected List<Record> jsonArrayBody() {
        String raw = getRawData();
        if (StrKit.isBlank(raw)) {
            return new ArrayList<>();
        }
        try {
            // 解析成 List<Map<String,Object>>
            List<Map<String, Object>> list = JSON.parseObject(raw,
                    new TypeReference<List<Map<String, Object>>>() {
                    });

            List<Record> records = new ArrayList<>();
            if (list != null) {
                for (Map<String, Object> map : list) {
                    records.add(new Record().setColumns(map));
                }
            }
            return records;
        } catch (Exception e) {
            throw new RuntimeException(TipCode.PARAM_ERROR + ": JSON 解析失败", e);
        }
    }


    /** 取字符串，空则返回 defaultVal */
    protected String getStr(Record rec, String col, String defaultVal) {
        String v = rec.getStr(col);
        return v == null ? defaultVal : v;
    }

    /** 取 Integer，空则返回 defaultVal */
    protected Integer getInt(Record rec, String col, Integer defaultVal) {
        Integer v = rec.getInt(col);
        return v == null ? defaultVal : v;
    }

    /** 取 Long，空则返回 defaultVal */
    protected Long getLong(Record rec, String col, Long defaultVal) {
        Long v = rec.getLong(col);
        return v == null ? defaultVal : v;
    }

    /** 取 BigDecimal，空则返回 defaultVal */
    protected BigDecimal getDecimal(Record rec, String col, BigDecimal defaultVal) {
        BigDecimal v = rec.getBigDecimal(col);
        return v == null ? defaultVal : v;
    }

    /** 任意类型：空则返回 defaultVal */
    @SuppressWarnings("unchecked")
    protected <T> T getOrDefault(Record rec, String col, T defaultVal) {
        Object v = rec.get(col);
        return v == null ? defaultVal : (T) v;
    }

}
